package cn.bj.xd.mdy.util;

import cn.bj.xd.mdy.exception.MdyHttpException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;

import java.io.IOException;
import java.util.Map;

/**
 * HTTP请求工具类
 *
 * @Author dongjunjie
 * @Date 2022-01-05 19:32:15
 */
@Slf4j
@UtilityClass
public class HttpUtil {
    public static <T> String post(String url, Map<String, String> headers, T bodyObject) throws MdyHttpException {
        OkHttpClient client = new OkHttpClient();
        MediaType mediaType = MediaType.parse("application/json");
        ObjectMapper mapper = new ObjectMapper();
        String content;
        try {
            content = mapper.writeValueAsString(bodyObject);
        } catch (JsonProcessingException e) {
            throw new MdyHttpException(e);
        }
        RequestBody body = RequestBody.create(mediaType, content);
        Request.Builder builder = new Request.Builder();
        builder.url(url).post(body).addHeader("charset", "utf-8");
        if (headers != null && !headers.isEmpty()) {
            headers.keySet().forEach(e -> builder.addHeader(e, headers.get(e)));
        }
        Request request = builder.build();
        Response response = null;
        try {
            try {
                log.info("HttpUtil send request, url: {}, content: {}", url, content);
                response = client.newCall(request).execute();
                String responseStr = response.body().string();
                log.info("HttpUtil send response, url: {}, content: {}", url, responseStr);
                if (!response.isSuccessful()) {
                    throw new MdyHttpException("HttpUtil send error, meta info: " + content + ", response body: " + responseStr);
                }
                return responseStr;
            } catch (IOException e) {
                throw new MdyHttpException("HttpUtil send error, meta info: " + content);
            }
        } finally {
            if (response != null) {
                try {
                    response.body().close();
                } catch (Exception e) {
                    //log.error(" response.body().close() Exception", e);
                }
            }
        }
    }

    public static <T> String get(String url, Map<String, String> headers, T bodyObject, Map<String, String> params) {
        OkHttpClient client = new OkHttpClient();
        MediaType mediaType = MediaType.parse("application/json");
        ObjectMapper mapper = new ObjectMapper();
        RequestBody body = RequestBody.create(mediaType, "");
        Request.Builder builder = new Request.Builder();
        if (params != null && !params.isEmpty()) {
            url = url + "?" + params.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).reduce((a, b) -> a + "&" + b).get();
        }
        builder.url(url).get().addHeader("charset", "utf-8");
        if (headers != null && !headers.isEmpty()) {
            headers.keySet().forEach(e -> builder.addHeader(e, headers.get(e)));
        }
        Request request = builder.build();
        Response response = null;
        try {
            try {
                log.info("HttpUtil send request, url: {}", url);
                response = client.newCall(request).execute();
                String responseStr = response.body().string();
                log.info("HttpUtil send response, content: {}", responseStr);
                if (!response.isSuccessful()) {
                    throw new MdyHttpException("HttpUtil send error " + ", response body: " + responseStr);
                }
                return responseStr;
            } catch (IOException e) {
                throw new MdyHttpException("HttpUtil send error, url: " + url);
            }
        } finally {
            if (response != null) {
                try {
                    response.body().close();
                } catch (Exception e) {
                    //log.error(" response.body().close() Exception", e);
                }
            }
        }
    }
}
